package com.example.laixunlong.control;

import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.laixunlong.R;
import com.example.laixunlong.pojo.Json;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Objects;

public class PowerGain_quanxian extends AppCompatActivity {

    Button power_button_1,power_button_2,power_button_3,power_button_4,power_button_5,power_button_6;
    EditText power_input_1,power_input_2,power_input_3,power_input_4;
    TextView contacts_table_1;
    ImageView power_image_1;

    public static int True= PackageManager.PERMISSION_GRANTED;//完全开启
    public static int False= PackageManager.PERMISSION_DENIED;//未开启
    public static final int request_code=1;//回调编号,随意设置,仅需要和回调函数中的判断量保持一致即可
    DXjianting dx=null;
    ActivityResultLauncher<Intent> resultLauncher=null;
    Uri picuri=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.power_gain_quanxian);
        power_button_1=findViewById(R.id.power_button_1);
        power_button_2=findViewById(R.id.power_button_2);
        power_button_3=findViewById(R.id.power_button_3);
        power_button_4=findViewById(R.id.power_button_4);
        power_button_5=findViewById(R.id.power_button_5);
        power_button_6=findViewById(R.id.power_button_6);
        power_input_1=findViewById(R.id.power_input_1);
        power_input_2=findViewById(R.id.power_input_2);
        contacts_table_1=findViewById(R.id.contacts_table_1);
        power_image_1=findViewById(R.id.power_image_1);
        power_input_3=findViewById(R.id.power_input_3);
        power_input_4=findViewById(R.id.power_input_4);
        /*获取短信权限*/
        power_button_1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
        /*获取联系人权限,  下文的获取判定应该在onCreate方法中进行,但为了逻辑清晰,使用事件进行触发*/
        power_button_2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getContactsPower();
            }
        });
        /*获取所有联系人*/
        power_button_3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ArrayList<Json> j= getContactItem();
                StringBuffer s=new StringBuffer();
                for(Json i:j)
                {
                    s.append("\n").append(i.getKey()).append(":").append(i.getValue());
                }
                contacts_table_1.setText(s.toString());
            }
        });
        /*添加联系人*/
        power_button_4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name= power_input_1.getText().toString();
                String phone= power_input_2.getText().toString();
                String email="1520359856@qq.com";
                if(phone.equals("") || name.equals(""))
                {Toast.makeText(PowerGain_quanxian.this,"存在空值",Toast.LENGTH_SHORT).show();}
                else
                {
                    addContactItem(name,phone,email);
                }
            }
        });



    /*重点!!  发送彩信==============================================================================*/
        //设置可回传数据的跳转方式
        resultLauncher=registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
            @Override/*当有页面返回到此页面时触发*/
            public void onActivityResult(ActivityResult result) {
                if (result.getResultCode()==RESULT_OK)
                {
                    //获取返回中携带的数据
                    Intent intent=result.getData();
                    /*从数据中获取有效内容
                        getExtras() 获取回传对象Bundle
                        getData()   获取资源绝对路径Uri
                    */
                    picuri=intent.getData();
                    if(picuri!=null)
                    {
                        power_image_1.setImageURI(picuri);//设置显示图片
                    }
                }
            }
        });
        //通过点击图片跳转到相册
        power_image_1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(Intent.ACTION_GET_CONTENT);//通过隐式意图跳转
                intent.setType("image/*");//设置选中资源类型,一般的跳转此项为null,当为预设值时,会定位到静态资源位置
                resultLauncher.launch(intent);//
            }
        });
        //点击发送彩信
        power_button_5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String phone=power_input_3.getText().toString();
                String value=power_input_4.getText().toString();
                if(!phone.equals("") && !value.equals(""))
                {
                    SendingMessage("标题",phone,value);
                }
            }
        });
        /*监听短信消息*/
        power_button_6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Uri uri=Uri.parse("content://sms");//获取短信开头的uri
                dx=new DXjianting(PowerGain_quanxian.this);//注册短信监听器
                getContentResolver().registerContentObserver(uri,true,dx);//动态获取权限,弹窗
            }
        });
    }
    /*联系人权限获取*/
    public void getContactsPower()
    {
        String a=Manifest.permission.READ_CONTACTS;//联系人读权限
        String b=Manifest.permission.WRITE_CONTACTS;//联系人写权限
        String[] pow=new String[]{a,b};//整合成数组,因为权限判断方法接收的对象是数组
        //API23以后才有动态权限管理
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M)
        {
            Log.e("过程","开始判断权限");
            int pd=True;
            //判断某权限是否开启的方法,根据开启的程度,有多个等级
            for(String p:pow)
            {
                int t=ContextCompat.checkSelfPermission(PowerGain_quanxian.this,p);
                if(t!=True)
                {
                    Log.e("过程","存在未开启的权限");
                    pd=False;
                    break;
                }
            }
            Log.e("过程",pd+"");
            if(pd!=True)//存在未开启的权限,则请求系统弹窗
            {
                Log.e("过程","开始请求弹窗");
                //申请弹窗的方法需要接收一个字符串数组
                //权限设置情况需在下文回调方法中查看
                ActivityCompat.requestPermissions(PowerGain_quanxian.this,pow,request_code);
            }
        }
    }
    /*添加联系人*/
    public void addContactItem(String name,String phone,String email)
    {
        ContentResolver resolver=getContentResolver();
        //插入空对象,获取raw_contact表中的id
        ContentValues value1=new ContentValues();
        Uri uri=resolver.insert(ContactsContract.RawContacts.CONTENT_URI,value1);
        long uid= ContentUris.parseId(uri);

        //方式1:逐行写入
        //根据id设置data表,
        /*该表的存在是为了让一个用户存在多个通讯录,因此有多个外键,需要在表中插入多行数据
         * 第一行用于关联,第二行开始才是用户的数据*/
        ContentValues value2=new ContentValues();
        value2.put(ContactsContract.Contacts.Data.RAW_CONTACT_ID,uid);//添加raw_contact_id(raw_contact表的主键),
        value2.put(
                ContactsContract.Contacts.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
        );//添加mimetype_id(联系人类型信息),有专门的匹配项,1表示网络通讯录联系人
        value2.put(ContactsContract.Contacts.Data.DATA2,name);//设置通讯录的用户名,如果用户存在多个通讯录,则可以通过名称关联与跳转
        resolver.insert(ContactsContract.Data.CONTENT_URI,value2);//将上文做好的联系人对象写入(此时只有用户名)
        //设置data表中的电话号码,在此表设置可直接在联系人中查看,也可以在其他类型的联系人表中设置
        /*中转变量*/ContentValues value3=new ContentValues();
        value3.put(ContactsContract.Contacts.Data.RAW_CONTACT_ID,uid);
        value3.put(
                ContactsContract.Contacts.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
        );//设置电话号码的所在通讯录,此处和上面的名字一样,设置为普通联系人
        value3.put(ContactsContract.Contacts.Data.DATA1,phone);//设置电话号码
        value3.put(ContactsContract.Contacts.Data.DATA2, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);//设置电话号码类型,此处为工作电话(1家庭,2工作)
        resolver.insert(ContactsContract.Data.CONTENT_URI,value3);
        //设置data表中的邮箱
        /*中转变量*/ContentValues value4=new ContentValues();
        value4.put(ContactsContract.Contacts.Data.RAW_CONTACT_ID,uid);
        value4.put(
                ContactsContract.Contacts.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
        );//设置电话号码的所在通讯录,此处和上面的名字一样,设置为普通联系人
        value4.put(ContactsContract.Contacts.Data.DATA1,email);//设置电话号码
        value4.put(ContactsContract.Contacts.Data.DATA2, ContactsContract.CommonDataKinds.Email.TYPE_MOBILE);//设置邮箱类型(1家庭,2工作)
        resolver.insert(ContactsContract.Data.CONTENT_URI,value4);



        //方式2:事务操作器
        //创建主记录,获取id
                /*
                ContentProviderOperation data1=ContentProviderOperation
                        .newInsert(ContactsContract.RawContacts.CONTENT_URI)
                        .withValue(ContactsContract.RawContacts.ACCOUNT_NAME,null)
                        .build();
                */

        //插入用户名
                /*
                ContentProviderOperation data2=ContentProviderOperation
                        .newInsert(ContactsContract.Data.CONTENT_URI)
                        .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID,0)
                        .withValue(ContactsContract.Contacts.Data.MIMETYPE,ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                        .withValue(ContactsContract.Contacts.Data.DATA2,name)
                        .build();
                */

        //插入电话号码
                /*
                ContentProviderOperation data3=ContentProviderOperation
                        .newInsert(ContactsContract.Data.CONTENT_URI)
                        .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID,0)
                        .withValue(ContactsContract.Contacts.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                        .withValue(ContactsContract.Contacts.Data.DATA1,phone)
                        .withValue(ContactsContract.Contacts.Data.DATA2,ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
                        .build();
                */

        //插入邮箱
                /*
                ContentProviderOperation data4=ContentProviderOperation
                        .newInsert(ContactsContract.Data.CONTENT_URI)
                        .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID,0)
                        .withValue(ContactsContract.Contacts.Data.MIMETYPE,ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
                        .withValue(ContactsContract.Contacts.Data.DATA1,email)
                        .withValue(ContactsContract.Contacts.Data.DATA2,ContactsContract.CommonDataKinds.Email.TYPE_MOBILE)
                        .build();
                */

        //批处理集合
                /*
                ArrayList<ContentProviderOperation> op=new ArrayList<>();
                op.add(data1);
                op.add(data2);
                op.add(data3);
                op.add(data4);
                try {
                    resolver.applyBatch(ContactsContract.AUTHORITY,op);
                } catch (OperationApplicationException e) {
                    throw new RuntimeException(e);
                } catch (RemoteException e) {
                    throw new RuntimeException(e);
                }
                */
        /*发送添加成功通知栏*/
        Toast.makeText(PowerGain_quanxian.this,"添加成功",Toast.LENGTH_SHORT).show();
    }
    /*搜索联系人*/
    @SuppressLint("Range")/*逃避空值错误*/
    public ArrayList<Json> getContactItem()
    {
        String name= power_input_1.getText().toString();
        ContentResolver resolver=getContentResolver();
        ArrayList<Json> json=new ArrayList<>();
        if(name.equals(""))//没有名称对象,则查询全部
        {
            Log.e("流程","开始检索");
            Cursor cursor= resolver.query(
                    ContactsContract.RawContacts.CONTENT_URI,/*查表位置*/
                    new String[]{ContactsContract.RawContacts._ID},/*查询列位置,普通联系人id*/
                    null,/*查询内容,无内容则获取全部*/
                    null,
                    null);
            /*返回结果为多行联系人id*/
            while(cursor.moveToNext()){
                int raw=cursor.getInt(0);
                /*通过联系人id生成uri,该对象用于在data表中获取位置*/
                Uri uri=Uri.parse("content://com.android.contacts/contacts/"+raw+"/data");
                Cursor c= resolver.query(
                        uri,/*表位置*/
                        new String[]{/*列位置*/
                                ContactsContract.Contacts.Data.MIMETYPE,
                                ContactsContract.Contacts.Data.DATA1,
                                ContactsContract.Contacts.Data.DATA2
                        },
                        null,/*检索内容*/
                        null,
                        null);
                String username="",userphone="",useremail="";
                while(c.moveToNext())
                {
                    /*因为用户的数据保存在不同的行中,所以需要对每一行所属的数据类型进行划分*/
                    String data1=c.getString(c.getColumnIndex(ContactsContract.Contacts.Data.DATA1));//本行的数据部分
                    String type=c.getString(c.getColumnIndex(ContactsContract.Contacts.Data.MIMETYPE));//本列所属类型
                    if(Objects.equals(type, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE))//联系人名字
                    {
                        username=data1;
                    }
                    else if(Objects.equals(type, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE))//;联系人电话
                    {
                        userphone=data1;
                    }
                    else if(Objects.equals(type, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE))//联系人邮箱
                    {
                        useremail=data1;
                    }
                }
                c.close();//关闭data表的流
                if(!Objects.equals(username, "") && !Objects.equals(userphone, ""))
                {
                    json.add(new Json(username,userphone));
                    Log.e("获取到内容",":\n联系人:"+username+",电话:"+userphone+",邮箱:"+useremail);
                }
            }
        }
        else
        {}
        return json;
    }
    /*发送彩信*/
    public void SendingMessage(String Title,String phone,String value)
    {
        Intent intent=new Intent(Intent.ACTION_SEND);//跳转对象为短信,但该名称被很多软件设置,因此会出现可选列表
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//跳转意图为一个新的页面
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//跳转意图携带的uri可被目标读取
        intent.putExtra("address",phone);//设置单向传递的数据,这些数据的键名是预设值,不可随意更改
        intent.putExtra("subject",Title);
        intent.putExtra("sms_body",value);
        intent.putExtra(Intent.EXTRA_STREAM,picuri);//传递图片数据,其实只是uri
        intent.setType("image/*");//告知图片类型
        startActivity(intent);
    }
    @Override/*页面销毁时*/
    protected void onDestroy() {
        super.onDestroy();
        if(dx!=null) {
            getContentResolver().unregisterContentObserver(dx);//关闭短信监听
        }
    }

    @Override/*用户点击权限控制窗口后的回调函数*/
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        /*数组中的参数为权限授权情况,下文进行遍历判断授权情况*/
        int pd=True;
        for(int i:grantResults)
        {
            if(i!=True)
            {
                pd=False;
            }
        }
        if(pd!=True)//如果存在未授权的权限,则跳转到权限设置界面
        {
            Intent intent=new Intent();
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);//使用隐式意图
            intent.setData(Uri.fromParts("package",getPackageName(),null));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }
    }
    /*监听器*/
    public static class DXjianting extends ContentObserver{
        private final Context context;
        public DXjianting(Context context) {
            super(new Handler(Looper.getMainLooper()));
            this.context=context;
        }

        @Override/*短信监听回调方法,每监听到一条短信,则执行一次*/
        @SuppressLint("Range")
        public void onChange(boolean selfChange,Uri uri) {
            super.onChange(selfChange,uri);
            /*
            onChange方法在接收到一条短信时回多次调用,详细调用情况如下:后面的数字是短信在数据库中的id,
            1,in_uri=content://sms/raw/20   首次收到消息
            2,in_uri=content://sms/inbox/20 消息弹出窗口
            3,in_uri=content://sms          点击消息已读
            */
            /*我们只需要其中能造成弹窗的那个,因此做出如下判断:*/
            //Log.e("请求头",uri.toString());
            if(uri == null)//为空时不执行
            {}
            else if(uri.toString().contains("content://sms/raw") || uri.toString().equals("content://sms"))//接收和已读时不执行
            {}
            else if(uri.toString().contains("content://sms/status"))/*剩下的就是弹窗触发的监听*/
            {
                Cursor cursor =context.getContentResolver().query(
                        uri,
                        new String[]{
                                "address",
                                "body",
                                "date"
                        },
                        null,
                        null,
                        "date DESC");
                if(cursor.moveToNext())//获取并打印
                {
                     String phone=cursor.getString(cursor.getColumnIndex("address"));
                     String value=cursor.getString(cursor.getColumnIndex("body"));
                     Log.e("监听到:","号码:"+phone+",内容:"+value);
                }
                cursor.close();
            }
        }
    }
}
